/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package interfacesGraficas;

import interfacesGraficas.JDialogs.PantallaMaterialesModificar;
import interfacesGraficas.JDialogs.PantallaMaterialesNuevoTipo;
import DTOs.DTOMaterial;
import Fabricas.FabricaExpertos;
import entidadesNegocio.Material;
import entidadesNegocio.TipoMaterial;
import excepciones.ExpertoMaterialesException;
import expertos.ExpertoMateriales;
import interfacesGraficas.ModeloCombo.ModeloComboBoxTiposMat;
import interfacesGraficas.ModeloTablas.ModeloTablaMateriales;
import interfacesGraficas.ModeloTablas.ModeloTablaTiposMateriales;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import utilidades.UtilListas;

/**
 *
 * @author diego
 */
public class ControladorMateriales extends Controlador {

    PantallaMateriales pantalla;
    PantallaMaterialesModificar pantallaModificarMat;
    PantallaMaterialesNuevoTipo pantallaNuevoTipo;
    ExpertoMateriales experto;
    ModeloTablaMateriales modeloTablaMateriales;
    ModeloComboBoxTiposMat modeloComboTipos;
    Material materialSeleccionado; //Material que se va a guardar o modificar
    TipoMaterial tipoMatSeleccionado;//Tipo de Material que se va a modificar
    ModeloTablaTiposMateriales modeloTablaTiposMat;

    public ControladorMateriales() {
        pantalla = new PantallaMateriales();
        pantallaModificarMat = new PantallaMaterialesModificar(ControladorPrincipal.getInstancia().getPantallaPrincipal());
        pantallaNuevoTipo = new PantallaMaterialesNuevoTipo(ControladorPrincipal.getInstancia().getPantallaPrincipal());
        experto = (ExpertoMateriales) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.MATERIALES);
        modeloTablaMateriales = new ModeloTablaMateriales();
        pantalla.getTblMateriales().setModel(modeloTablaMateriales);
        //TODO: CORREGIR el ordenamiento de la tabla
        //pantalla.getTblMateriales().setAutoCreateRowSorter(true);
        modeloComboTipos = new ModeloComboBoxTiposMat();
        modeloTablaTiposMat = new ModeloTablaTiposMateriales();
        //tabla materiales
        pantalla.getTblMateriales().addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                int fila = pantalla.getTblMateriales().rowAtPoint(e.getPoint());
                materialSeleccionado = modeloTablaMateriales.buscarMaterial(pantalla.getTblMateriales().getValueAt(fila, 1).toString());
                if (e.getClickCount() == 2) {
                    modificarMaterial();
                }
            }
        });

        //boton nuevo material
        pantalla.getBtnNuevo().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                nuevoMaterial();
            }
        });
        //boton modificar material
        pantalla.getBtnModificarMat().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (materialSeleccionado != null) {
                    modificarMaterial();
                }
            }
        });
        //boton buscar material
        pantalla.getBtnBuscar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                buscarMateriales();
            }
        });
        pantalla.getTxtCodigo().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                buscarMateriales();
            }
        });
        pantalla.getTxtNombre().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                buscarMateriales();
            }
        });

        //boton nuevo tipo material
        pantalla.getBtnNuevoTipoMaterial().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                pantallaNuevoTipo.setVisible(true);
                pantallaNuevoTipo.setLocationRelativeTo(null);
                mostrarTiposMateriales();
            }
        });

        //boton eliminar
        pantalla.getBtnEliminarMaterial().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                eliminarMaterial();
            }
        });

        //boton salir
        pantalla.getBtnSalir().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                finalizar();
            }
        });

        /***************Pantalla modificar Mat***************************************/
        //boton guardar
        pantallaModificarMat.getBtnGuardar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                guardarMaterial();
            }
        });
        //combo tipo
        pantallaModificarMat.getCbxTipoMat().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (materialSeleccionado == null) {
                    generarCodigoMat();
                }
            }
        });
        //boton cancelar
        pantallaModificarMat.getBtnCancelar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                ocultarPantallaModificarMat();
            }
        });

        pantallaModificarMat.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                pantallaModificarMat.setVisible(false);
                limpiarPantallaModificar();
            }
        });

        /***************Pantalla nuevo Tipo*****************************************/
        pantallaNuevoTipo.getBtnGuardar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                guardarNuevoTipoMaterial();
            }
        });
        //tabla tipos materiales
        pantallaNuevoTipo.getTblTiposMateriales().addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                int fila = pantallaNuevoTipo.getTblTiposMateriales().rowAtPoint(e.getPoint());
                tipoMatSeleccionado = (TipoMaterial) modeloTablaTiposMat.getRow(fila);
                mostrarTipoMatSeleccionado();
            }
        });
        //boton eliminar tipo material
        pantallaNuevoTipo.getBtnEliminarTipoMat().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                eliminarTipoMaterial();
            }
        });
        pantallaNuevoTipo.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                pantallaNuevoTipo.setVisible(false);
                limpiarPantallaNuevoTipo();
            }
        });
        pantallaNuevoTipo.getBtnCancelar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                pantallaNuevoTipo.setVisible(false);
                limpiarPantallaNuevoTipo();
            }
        });
    }

    private void buscarMateriales() {
        if (!modeloTablaMateriales.getListaElementos().isEmpty()) {
            modeloTablaMateriales.clear();
        }
        try {
            modeloTablaMateriales.addAllRow(experto.buscarMateriales(armarDtoBusquedaMateriales()));
        } catch (ExpertoMaterialesException ex) {
            JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    private void nuevoMaterial() {
        materialSeleccionado = null;
        limpiarPantallaModificar();
        pantallaModificarMat.setVisible(true);
        pantallaModificarMat.setLocationRelativeTo(null);
    }

    private void modificarMaterial() {
        pantallaModificarMat.setVisible(true);
        pantallaModificarMat.setLocationRelativeTo(null);
        mostrarMaterialPantallaModificar(materialSeleccionado);
    }

    private void mostrarMaterialPantallaModificar(Material materialSeleccionado) {
        pantallaModificarMat.getTxtCodigoMat().setText(materialSeleccionado.getCodigoMaterial());
        pantallaModificarMat.getTxtNombreMat().setText(materialSeleccionado.getNombreMaterial());
        pantallaModificarMat.getTxtTamañoMat().setText(materialSeleccionado.getTamanioUnidadMaterial().toString());
        ((ModeloComboBoxTiposMat) pantallaModificarMat.getCbxTipoMat().getModel()).setTipoSeleccionado(materialSeleccionado.getTipoMaterial());
        pantallaModificarMat.getCbxUnidadMat().setSelectedItem(materialSeleccionado.getUnidadMedidaMaterial());
    }

    private void guardarMaterial() {
        //TODO: CORREGIR: al guardar el material si no se selecciona una unidad de medida, tira error y luego lo agrega a la tabla.
        if (materialSeleccionado == null) {
            materialSeleccionado = new Material();
        }
        materialSeleccionado.setCodigoMaterial(pantallaModificarMat.getTxtCodigoMat().getText());
        materialSeleccionado.setNombreMaterial(pantallaModificarMat.getTxtNombreMat().getText());
        materialSeleccionado.setUnidadMedidaMaterial(pantallaModificarMat.getCbxUnidadMat().getSelectedItem().toString());
        if (pantallaModificarMat.getTxtTamañoMat().getText().length() != 0) {
            materialSeleccionado.setTamanioUnidadMaterial(Double.valueOf(pantallaModificarMat.getTxtTamañoMat().getText()));
        } else {
            materialSeleccionado.setTamanioUnidadMaterial(0d);
        }
        materialSeleccionado.setTipoMaterial(((ModeloComboBoxTiposMat) pantallaModificarMat.getCbxTipoMat().getModel()).getTipoSeleccionado());
        try {
            experto.guardar(materialSeleccionado);

        } catch (ExpertoMaterialesException ex) {
            JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "ATENCIÓN", JOptionPane.WARNING_MESSAGE);
        }
        modeloTablaMateriales.quitarMaterialLista(materialSeleccionado);
        modeloTablaMateriales.addRow(materialSeleccionado);
        pantallaModificarMat.setVisible(false);
        materialSeleccionado = null;
        JOptionPane.showMessageDialog(pantalla, "Material Guardado Correctamente", "Información", JOptionPane.INFORMATION_MESSAGE);
    }

    private void eliminarMaterial() {
        if (materialSeleccionado != null) {

            int seleccion = JOptionPane.showOptionDialog(
                    null,
                    "Esta seguro que desea eliminar material: \nCódigo: " + materialSeleccionado.getCodigoMaterial() + ". Nombre: " + materialSeleccionado.getNombreMaterial(),
                    "ELIMINAR MATERIAL",
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    null, // null para icono por defecto.
                    new Object[]{"Aceptar", "Cancelar"}, // null para YES, NO y CANCEL
                    "Cancelar");

            if (seleccion == 0) {
                try {
                    experto.eliminarMaterial(materialSeleccionado);
                    modeloTablaMateriales.quitarMaterialLista(materialSeleccionado);
                    JOptionPane.showMessageDialog(pantalla, "Material Eliminado Correctamente", "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
                } catch (ExpertoMaterialesException ex) {
                    JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "ERROR", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }

    private void ocultarPantallaModificarMat() {
        limpiarPantallaModificar();
        pantallaModificarMat.setVisible(false);
    }

    public void iniciar() {
        pantalla.getCbxTipo().setModel(modeloComboTipos);
        if (!((Thread) this).isAlive()) {//si el hilo esta corriendo, no debe hacer nada
            pantalla.getBtnNuevo().setEnabled(false);
            pantalla.getBtnNuevoTipoMaterial().setEnabled(false);
            pantalla.getBtnBuscar().setEnabled(false);
            this.start();//llena los combos llama al metodo run()
        }
        pantalla.setVisible(true);
        //pantalla nuevo tipo
        pantallaNuevoTipo.getTblTiposMateriales().setModel(modeloTablaTiposMat);

    }

    @Override
    public void finalizar() {
        pantalla.setVisible(false);
    }

    @Override
    public void continuar() {
        pantalla.setVisible(true);
    }

    private void limpiarPantallaModificar() {
        pantallaModificarMat.getTxtCodigoMat().setText("");
        pantallaModificarMat.getTxtNombreMat().setText("");
        pantallaModificarMat.getTxtTamañoMat().setText("");
        pantallaModificarMat.getCbxTipoMat().setSelectedIndex(0);
        pantallaModificarMat.getCbxUnidadMat().setSelectedIndex(0);
    }

    private void limpiarPantallaNuevoTipo() {
        pantallaNuevoTipo.getTxtCodigoTipo().setText("");
        pantallaNuevoTipo.getTxtTipoMat().setText("");
    }

    /**
     * Guarda unn tipo de Material
     */
    private void guardarNuevoTipoMaterial() {
        //TODO: Generar codigo de tipo de Material, y validar que no exista material con dicho codigo
        if (tipoMatSeleccionado == null) {
            tipoMatSeleccionado = new TipoMaterial();
        }
        tipoMatSeleccionado.setCodigotipomaterial(pantallaNuevoTipo.getTxtCodigoTipo().getText());
        tipoMatSeleccionado.setNombretipomaterial(pantallaNuevoTipo.getTxtTipoMat().getText());
        try {
            experto.guardarNuevoTipo(tipoMatSeleccionado);

        } catch (ExpertoMaterialesException ex) {
            JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "ATENCIÓN", JOptionPane.WARNING_MESSAGE);
        }
        JOptionPane.showMessageDialog(pantalla, "Tipo de Material Guardado Correctamente", "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
        limpiarPantallaNuevoTipo();
        pantallaNuevoTipo.setVisible(false);
        modeloComboTipos.quitarTipo(tipoMatSeleccionado);
        modeloComboTipos.getListaTipos().add(tipoMatSeleccionado);
        UtilListas.ordenar(modeloComboTipos.getListaTipos(), "codigotipomaterial");
        pantalla.getCbxTipo().setModel(new ModeloComboBoxTiposMat(modeloComboTipos.getListaTipos()));
        pantallaModificarMat.getCbxTipoMat().setModel(new ModeloComboBoxTiposMat(modeloComboTipos.getListaTipos()));
        tipoMatSeleccionado = null;
    }

    private void eliminarTipoMaterial() {
        if (tipoMatSeleccionado != null) {
            try {
                experto.eliminarTipoMat(tipoMatSeleccionado);
                JOptionPane.showMessageDialog(pantalla, "Tipo de Material eliminado correctamente", "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
                limpiarPantallaNuevoTipo();
                pantalla.getCbxTipo().setModel(new ModeloComboBoxTiposMat(experto.buscarTiposMateriales()));
                modeloTablaTiposMat.clear();
                modeloTablaTiposMat.addAllRow(((ModeloComboBoxTiposMat) pantalla.getCbxTipo().getModel()).getListaTipos());
            } catch (ExpertoMaterialesException ex) {
                JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "ERROR", JOptionPane.WARNING_MESSAGE);
            }
        }
    }

    /**
     * Muestra los tipos de los materiales en la pantalla Tipos Materiales
     */
    private void mostrarTiposMateriales() {
        modeloTablaTiposMat.setListaElementos(((ModeloComboBoxTiposMat) pantalla.getCbxTipo().getModel()).getListaTipos());
    }

    /**
     * Muestra el tipo de material seleccionado, para que pueda ser modificado o eliminado
     */
    private void mostrarTipoMatSeleccionado() {
        pantallaNuevoTipo.getTxtCodigoTipo().setText(tipoMatSeleccionado.getCodigotipomaterial());
        pantallaNuevoTipo.getTxtTipoMat().setText(tipoMatSeleccionado.getNombretipomaterial());
    }

    private void generarCodigoMat() {
        if (((ModeloComboBoxTiposMat) pantallaModificarMat.getCbxTipoMat().getModel()).getTipoSeleccionado() != null) {
            pantallaModificarMat.getTxtCodigoMat().setText(experto.generarCodigoMaterial(((ModeloComboBoxTiposMat) pantallaModificarMat.getCbxTipoMat().getModel()).getTipoSeleccionado()));
        }
    }

    private DTOMaterial armarDtoBusquedaMateriales() {
        DTOMaterial dtoBusqueda = new DTOMaterial();

        dtoBusqueda.setCodigo(pantalla.getTxtCodigo().getText());
        dtoBusqueda.setNombre(pantalla.getTxtNombre().getText());
        if (pantalla.getCbxTipo().getSelectedIndex() > 0) {
            dtoBusqueda.setTipo(pantalla.getCbxTipo().getSelectedItem().toString());
        }

        return dtoBusqueda;
    }

    @Override
    public JInternalFrame getPantalla() {
        return pantalla;
    }

    /**
     * el hilo lo uso para llenar los combos, algo que hace que la pantalla quede demorada
     */
    @Override
    public void start() {
        continuar = true;
        super.start();
    }
    private boolean continuar = true;

    @Override
    public void run() {
        while (continuar) {
            pantalla.getCbxTipo().setVisible(false);
            pantalla.getLblTipo().setText("CARGANDO TIPOS MATERIALES");
            pantalla.getLblTipo().setForeground(Color.BLUE);
            if (!experto.buscarTiposMateriales().isEmpty()) {
                modeloComboTipos.setListaCombo(experto.buscarTiposMateriales());
                pantallaModificarMat.getCbxTipoMat().setModel(new ModeloComboBoxTiposMat(modeloComboTipos));
            }
            pantalla.getCbxTipo().setVisible(true);
            pantalla.getLblTipo().setText("Tipo");
            pantalla.getLblTipo().setForeground(Color.BLACK);
            pantalla.getBtnNuevo().setEnabled(true);
            pantalla.getBtnNuevoTipoMaterial().setEnabled(true);
            pantalla.getBtnBuscar().setEnabled(true);
            continuar = false;
        }
    }
}
